using System.Net.Sockets;
using System.Net;
using Google.Protobuf;
using muduoDotNet.Common;

namespace muduoDotNet
{
    /// <summary>
    /// TcpClient类，客户端的核心组件
    /// </summary>
    public class TcpClient : IDisposable
    {
        private readonly EventLoop _loop;
        private readonly IPEndPoint _serverAddr;
        private readonly Socket _socket;
        private readonly Channel _channel;
        private TcpConnection _connection;
        private bool _connected;
        private bool _disposed;
        
        // 新增模块
        private ConnectionPool _connectionPool;
        private RecoveryManager _recoveryManager;
        private Configuration _configuration;
        
        // 协议编解码相关
        private IProtocolCodec? _protocolCodec;
        private IProtocolMessageHandler? _messageHandler;

        public TcpClient(EventLoop loop, IPEndPoint serverAddr)
        {
            _loop = loop ?? throw new ArgumentNullException(nameof(loop));
            _serverAddr = serverAddr ?? throw new ArgumentNullException(nameof(serverAddr));
            _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            _channel = new Channel(loop, _socket.Handle.ToInt32());
            _connection = null;
            _connected = false;
            _disposed = false;
            
            // 初始化配置管理器
            _configuration = Configuration.GetInstance();
            
            // 初始化连接池（如果启用）
            if (_configuration.GetValue<bool>("performance.connection.pool.enabled", false))
            {
                var minPoolSize = _configuration.GetValue<int>("performance.connection.pool.min", 5);
                var maxPoolSize = _configuration.GetValue<int>("performance.connection.pool.max", 100);
                _connectionPool = new ConnectionPool(loop, serverAddr, minPoolSize, maxPoolSize);
            }
            
            // 初始化恢复管理器（如果启用）
            if (_configuration.GetValue<bool>("network.recovery.enabled", false))
            {
                var maxReconnectAttempts = _configuration.GetValue<int>("network.reconnect.attempts", 5);
                var reconnectIntervalMs = _configuration.GetValue<int>("network.reconnect.interval.ms", 5000);
                _recoveryManager = new RecoveryManager(maxReconnectAttempts, reconnectIntervalMs);
            }
            
            // 初始化协议支持
            _protocolCodec = new ProtobufCodec(); // 默认使用protobuf编解码器

            // 注册Socket到管理器
            SocketManager.RegisterSocket(_socket);

            // 设置Socket为非阻塞
            _socket.Blocking = false;

            // 设置Channel的回调
            _channel.ReadCallback = HandleRead;
            _channel.WriteCallback = HandleWrite;
            _channel.ErrorCallback = HandleError;
        }

        public TcpClient(EventLoop loop, string serverIp, int serverPort)
            : this(loop, new IPEndPoint(IPAddress.Parse(serverIp), serverPort))
        { }

        public EventLoop Loop => _loop;
        public IPEndPoint ServerAddr => _serverAddr;
        public bool Connected => _connected;
        public TcpConnection Connection => _connection;
        
        // 新增属性
        public ConnectionPool ConnectionPool => _connectionPool;
        public RecoveryManager RecoveryManager => _recoveryManager;
        public Configuration Configuration => _configuration;
        
        // 协议相关属性
        public IProtocolCodec? ProtocolCodec
        {
            get => _protocolCodec;
            set => _protocolCodec = value;
        }
        
        public IProtocolMessageHandler? MessageHandler
        {
            get => _messageHandler;
            set => _messageHandler = value;
        }

        // 事件回调
        public Action<TcpConnection> ConnectionCallback { get; set; }
        public Action<TcpConnection, Buffer> MessageCallback { get; set; }
        public Action<TcpConnection> WriteCompleteCallback { get; set; }

        /// <summary>
        /// 连接服务器
        /// </summary>
        public void Connect()
        {
            if (!_connected)
            {
                try
                {
                    // 增加活跃连接计数
                    PerformanceCounters.IncrementActiveConnections();
                    
                    // 尝试从连接池获取连接
                    if (_connectionPool != null)
                    {
                        _connection = _connectionPool.AcquireConnection();
                        if (_connection != null)
                        {
                            _connected = true;
                            _connection.ConnectionCallback = ConnectionCallback;
                            _connection.MessageCallback = MessageCallback;
                            _connection.WriteCompleteCallback = WriteCompleteCallback;
                            _connection.CloseCallback = HandleClose;
                            ConnectionCallback?.Invoke(_connection);
                            return;
                        }
                    }
                    
                    // 如果连接池不可用或没有可用连接，则创建新连接
                    // 开始异步连接
                    var result = _socket.BeginConnect(_serverAddr, ConnectCallback, _socket);
                    
                    // 检查连接是否立即完成
                    if (result.AsyncWaitHandle.WaitOne(0))
                    {
                        // 连接立即完成，处理连接完成
                        _socket.EndConnect(result);
                        _loop.RunInLoop(HandleConnectComplete);
                    }
                }
                catch (SocketException ex)
                {
                    // 记录连接失败
                    PerformanceCounters.IncrementFailedConnections();
                    PerformanceCounters.IncrementNetworkExceptions();
                    Logger.Error($"Socket connect error: {ex.Message}");
                }
            }
        }

        /// <summary>
        /// 异步连接回调
        /// </summary>
        /// <param name="ar">异步结果</param>
        private void ConnectCallback(IAsyncResult ar)
        {
            try
            {
                _socket.EndConnect(ar);
                _loop.RunInLoop(HandleConnectComplete);
            }
            catch (SocketException ex)
            {
                // 记录连接失败
                PerformanceCounters.IncrementFailedConnections();
                PerformanceCounters.IncrementNetworkExceptions();
                Logger.Error($"Socket connect callback error: {ex.Message}");
                _loop.RunInLoop(() =>
                {
                    // 连接失败，调用连接回调
                    _connected = false;
                    ConnectionCallback?.Invoke(null);
                    
                    // 如果启用了恢复管理，启动恢复
                    if (_recoveryManager != null && _connection != null)
                    {
                        _recoveryManager.StartRecovery(_connection);
                    }
                });
            }
        }

        /// <summary>
        /// 处理连接完成
        /// </summary>
        private void HandleConnectComplete()
        {
            _loop.AssertInLoopThread();
            
            if (!_connected)
            {
                _connected = true;
                
                // 创建TcpConnection对象
                var connName = $"client_connection";
                _connection = new TcpConnection(_loop, connName, _socket);
                
                // 设置协议编解码器
                if (_protocolCodec != null)
                {
                    _connection.ProtocolCodec = _protocolCodec;
                }
                if (_messageHandler != null)
                {
                    _connection.MessageHandler = _messageHandler;
                }
                
                // 设置回调
                _connection.ConnectionCallback = ConnectionCallback;
                _connection.MessageCallback = MessageCallback;
                _connection.WriteCompleteCallback = WriteCompleteCallback;
                _connection.CloseCallback = HandleClose;
                
                // 如果启用了恢复管理，注册连接
                if (_recoveryManager != null)
                {
                    _recoveryManager.RegisterConnection(_connection, ReconnectHandler);
                }
                
                // 建立连接
                _connection.ConnectEstablished();
            }
        }

        /// <summary>
        /// 重连处理函数
        /// </summary>
        /// <param name="connection">TCP连接</param>
        /// <returns>是否重连成功</returns>
        private bool ReconnectHandler(TcpConnection connection)
        {
            try
            {
                // 实现重连逻辑
                Logger.Info($"Reconnecting to {_serverAddr}...");
                Connect();
                return _connected;
            }
            catch (Exception ex)
            {
                Logger.Error($"Reconnect error: {ex.Message}", ex);
                return false;
            }
        }

        /// <summary>
        /// 断开连接
        /// </summary>
        public void Disconnect()
        {
            if (_connected)
            {
                _connected = false;
                _loop.RunInLoop(() =>
                {
                    if (_connection != null)
                    {
                        // 如果使用了连接池，归还连接到池中
                        if (_connectionPool != null)
                        {
                            _connectionPool.ReleaseConnection(_connection);
                        }
                        else
                        {
                            _connection.Shutdown();
                        }
                    }
                });
            }
        }

        /// <summary>
        /// 发送数据
        /// </summary>
        /// <param name="message">要发送的数据</param>
        public void Send(byte[] message)
        {
            if (_connected)
            {
                if (_loop.IsInLoopThread())
                {
                    _connection.Send(message);
                }
                else
                {
                    var messageCopy = new byte[message.Length];
                    System.Buffer.BlockCopy(message, 0, messageCopy, 0, message.Length);
                    _loop.RunInLoop(() => _connection.Send(messageCopy));
                }
            }
            else
            {
                Logger.Warning("Not connected, can't send data");
            }
        }

        /// <summary>
        /// 发送字符串
        /// </summary>
        /// <param name="message">要发送的字符串</param>
        public void Send(string message)
        {
            var bytes = System.Text.Encoding.UTF8.GetBytes(message);
            Send(bytes);
        }

        /// <summary>
        /// 发送protobuf消息
        /// </summary>
        /// <param name="message">要发送的protobuf消息</param>
        public void SendProtobufMessage(IMessage message)
        {
            if (!_connected)
            {
                Logger.Warning("Not connected, can't send protobuf message");
                return;
            }

            _connection?.SendProtobufMessage(message);
        }

        /// <summary>
        /// 处理读事件
        /// </summary>
        private void HandleRead()
        {
            _loop.AssertInLoopThread();
            // TcpConnection的HandleRead方法应该由其自己的Channel回调调用，
            // 而不是从TcpClient直接调用
        }

        /// <summary>
        /// 处理写事件
        /// </summary>
        private void HandleWrite()
        {
            _loop.AssertInLoopThread();
            // TcpConnection的HandleWrite方法应该由其自己的Channel回调调用，
            // 而不是从TcpClient直接调用
        }

        /// <summary>
        /// 处理错误事件
        /// </summary>
        private void HandleError()
        {
            _loop.AssertInLoopThread();
            // TcpConnection的HandleError方法应该由其自己的Channel回调调用，
            // 而不是从TcpClient直接调用
            
            // 如果启用了恢复管理，启动恢复
            if (_recoveryManager != null && _connection != null)
            {
                _recoveryManager.StartRecovery(_connection);
            }
        }

        /// <summary>
        /// 处理连接关闭
        /// </summary>
        /// <param name="conn">关闭的连接</param>
        private void HandleClose(TcpConnection conn)
        {
            _loop.AssertInLoopThread();
            
            if (_connected && conn == _connection)
            {
                _connected = false;
                
                // 减少活跃连接计数
                PerformanceCounters.DecrementActiveConnections();
                
                // 如果使用了连接池，不需要清理Channel
                if (_connectionPool == null)
                {
                    _connection = null;
                    // 清理Channel
                    _channel.DisableAll();
                    _channel.Remove();
                }
            }
        }

        public void Dispose()
        {
            if (!_disposed)
            {
                _disposed = true;
                
                // 断开连接
                Disconnect();
                
                // 释放连接池
                _connectionPool?.Dispose();
                
                // 释放恢复管理器
                _recoveryManager?.Dispose();
                
                // 清理资源
                if (_connection != null && _connectionPool == null)
                {
                    _connection.Dispose();
                    _connection = null;
                }
                
                try
                {
                    // 取消注册Socket
                    SocketManager.UnregisterSocket(_socket);
                    _socket.Close();
                }
                catch (Exception ex)
                {
                    Logger.Error($"Socket close error: {ex.Message}");
                }
                
                _channel.Dispose();
            }
        }
    }
}